package com.mstore.action;

import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;

import com.alipay.util.AlipayNotify;
import com.mstore.interceptor.Authority;
import com.mstore.pojo.Account;
import com.mstore.pojo.Balance;
import com.mstore.pojo.BalanceOrderInfo;
import com.mstore.pojo.BaseMember;
import com.mstore.pojo.BgiveRule;
import com.mstore.pojo.EnterpriseIntegralRule;
import com.mstore.pojo.Member;
import com.mstore.pojo.Shop;
import com.mstore.pojo.Tariff;
import com.mstore.pojo.User;
import com.mstore.service.AccountService;
import com.mstore.service.BalanceOrderInfoService;
import com.mstore.service.BalanceService;
import com.mstore.service.BaseMemberService;
import com.mstore.service.BgiveRuleService;
import com.mstore.service.EnterpriseIntegralRuleService;
import com.mstore.service.MemberService;
import com.mstore.service.ShopService;
import com.mstore.service.TariffService;
import com.mstore.service.UserService;
import com.mstore.util.CreateLaundry;
import com.opensymphony.xwork2.ActionContext;

public class BalanceOrderInfoAction extends BaseAction implements
		ServletRequestAware, ServletResponseAware {

	private static final long serialVersionUID = -4468207754509686621L;

	private HttpServletResponse response;

	private HttpServletRequest request;

	private BalanceOrderInfoService balanceOrderInfoService;

	private TariffService tariffService;

	private ShopService shopService;

	private BaseMemberService baseMemberService;

	private BgiveRuleService bGiveRuleService;

	private EnterpriseIntegralRuleService enterpriseIntegralRuleService;

	private MemberService memberService;

	private BalanceService balanceService;

	private AccountService accountService;

	private UserService userService;

	private static Logger logger = Logger
			.getLogger(BalanceOrderInfoAction.class.getName());

	/**
	 * 响应支付宝扫码支付接口回调网址return_url 为会员充值创建订单
	 */
	@Authority(actionName = "maccount", privilege = "pass")
	public String createAlipayBalanceOrderInfo() {
		try {
			Map<String, String> params = new HashMap<String, String>();
			@SuppressWarnings("rawtypes")
			Map requestParams = request.getParameterMap();
			for (@SuppressWarnings("rawtypes")
			Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
				String name = (String) iter.next();
				String[] values = (String[]) requestParams.get(name);
				String valueStr = "";
				for (int i = 0; i < values.length; i++) {
					valueStr = (i == values.length - 1) ? valueStr + values[i]
							: valueStr + values[i] + ",";
				}
				// 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
				// valueStr = new String(valueStr.getBytes("ISO-8859-1"),
				// "gbk");
				params.put(name, valueStr);
			}

			PrintWriter out = response.getWriter();
			if (AlipayNotify.verify(params)) {// 验证成功
				// ////////////////////////////////////////////////////////////////////////////////////////
				// 请在这里加上商户的业务逻辑程序代码

				// ——请根据您的业务逻辑来编写程序（以下代码仅作参考）——

				// 判断是否在商户网站中已经做过了这次通知返回的处理
				// 如果没有做过处理，那么执行商户的业务程序
				// 如果有做过处理，那么不执行商户的业务程序

				// 获取支付宝返回的goods_id，goods_id包含了goodId-baseMemberId-shopId
				String returnGoodsId = params.get("goods_id");
				String[] values = returnGoodsId.split("-");
				Long goodId = Long.parseLong(values[0]);
				Long shopId = Long.parseLong(values[1]);
				Long userId = Long.parseLong(values[2]);
				Long memberId = Long.parseLong(values[3]);

				// 业务参数查询
				Tariff tariff = tariffService.getTariffByGoodsId(goodId);
				Shop shop = new Shop();
				shop.setId(shopId);
				shop = shopService.getShopById(shop);

				// 填充订单参数
				BalanceOrderInfo balanceOrderInfo = new BalanceOrderInfo();
				balanceOrderInfo.setOrderId(new CreateLaundry()
						.createLaundryCode());
				balanceOrderInfo.setCreateTime(getCreateTime());
				balanceOrderInfo.setEaId(shop.getEaId());
				balanceOrderInfo.setShopId(shopId);
				balanceOrderInfo.setUserId(userId);
				balanceOrderInfo.setMemberId(memberId);
				balanceOrderInfo.setMoney(Double.valueOf(floatToScale(tariff
						.getFee())));
				balanceOrderInfo.setState(0); // 未支付

				// 创建特殊商品“充值”的订单
				balanceOrderInfoService.addBalanceOrderInfo(balanceOrderInfo);

				Map<String, Object> map = new HashMap<String, Object>();
				map.put("is_success", "T");
				map.put("out_trade_no", balanceOrderInfo.getOrderId());

				out.println(mapTojson(map)); // 请不要修改或删除

				// ——请根据您的业务逻辑来编写程序（以上代码仅作参考）——

				// ////////////////////////////////////////////////////////////////////////////////////////
			}
			else {// 验证失败
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("is_success", "F");
				map.put("error_code", "CREATE_TRADE_FAILURE");
				out.println(mapTojson(map));
			}
		}
		catch (Exception e) {
			logger.error("为会员充值创建订单报错", e);
		}

		ActionContext.getContext().getActionInvocation().getProxy()
				.setExecuteResult(false);
		return NONE;
	}

	/**
	 * 响应支付宝扫码支付接口回调网址notify_url 为会员充值生成交易流水账
	 */
	@Authority(actionName = "maccount", privilege = "pass")
	public String createAlipayBalanceTradeInfo() {

		try {
			Map<String, String> params = new HashMap<String, String>();
			@SuppressWarnings("rawtypes")
			Map requestParams = request.getParameterMap();
			for (@SuppressWarnings("rawtypes")
			Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
				String name = (String) iter.next();
				String[] values = (String[]) requestParams.get(name);
				String valueStr = "";
				for (int i = 0; i < values.length; i++) {
					valueStr = (i == values.length - 1) ? valueStr + values[i]
							: valueStr + values[i] + ",";
				}
				// 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
				// valueStr = new String(valueStr.getBytes("ISO-8859-1"),
				// "gbk");
				params.put(name, valueStr);
			}
			
			System.out.println(params);

			// 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
			// 通知业务参数
			String notify_data = new String(request.getParameter("notify_data")
					.getBytes("ISO-8859-1"), "UTF-8");
			// 参数格式请参见技术文档7.2章节

			// 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//

			PrintWriter out = response.getWriter();
			if (AlipayNotify.verify(params)) {// 验证成功
				// ////////////////////////////////////////////////////////////////////////////////////////
				// 请在这里加上商户的业务逻辑程序代码

				// ——请根据您的业务逻辑来编写程序（以下代码仅作参考）——

				// 判断是否在商户网站中已经做过了这次通知返回的处理
				// 如果没有做过处理，那么执行商户的业务程序
				// 如果有做过处理，那么不执行商户的业务程序

				// 获取订单号
				String outTradeNo = subStringFrom(notify_data,
						"<out_trade_no>", "</out_trade_no>");
				// 获取交易状态
				String tradeStatus = subStringFrom(notify_data,
						"<trade_status>", "</trade_status>");
				// 获取交易金额
				String totalFee = subStringFrom(notify_data,
						"<total_fee>", "</total_fee>");
				
				if ("TRADE_SUCCESS".equals(tradeStatus)
						|| "TRADE_FINISHED".equals(tradeStatus)) {
					BalanceOrderInfo balanceOrderInfo = balanceOrderInfoService
							.getBalanceOrderInfoByOrderId(outTradeNo);
					if (balanceOrderInfo != null) {
						// 设置实际交易金额
						balanceOrderInfo.setDirectPayMoney(Double.parseDouble(totalFee));
						
						Long memberId = balanceOrderInfo.getMemberId();
						Long eaId = balanceOrderInfo.getEaId();
						BaseMember baseMember = baseMemberService
								.getOneBaseMemberByMemberIdAndEaId(memberId, eaId);

						if (baseMember == null) {
							// 添加新数据
							baseMember = new BaseMember();
							baseMember.setBalance(balanceOrderInfo.getMoney());
							baseMember.setEaId(eaId);
							baseMember.setMemberId(memberId);
							baseMember.setCreateTime(getCreateTime());
							BgiveRule rule = bGiveRuleService.getEaGiveRule(eaId);
							if (rule != null)
								baseMember.setScore(rule.getGiveValue());
							else
								baseMember.setScore(0d);
							// 设置会员初始等级
							EnterpriseIntegralRule integralRule = enterpriseIntegralRuleService
									.getEnterpriseIntegralRuleByValues(eaId,
											baseMember.getScore().intValue());
							baseMember.setLevel(integralRule != null ? integralRule.getName() : null);

							baseMemberService.save(baseMember);
						}
						else {
							// 更新原有数据
							baseMember.setBalance(balanceOrderInfo.getMoney());
							baseMember.setEaId(eaId);
							baseMember.setMemberId(memberId);
							baseMemberService.updateBaseMemberBanlance(baseMember);
						}

						// 添加充值记录
						addBalance(balanceOrderInfo);
						
						// 更新充值订单状态为“已支付”
						balanceOrderInfoService.updateForState(outTradeNo);

						out.println("success"); // 请不要修改或删除
					}else { // 订单号不存在
						out.println("fail"); // 请不要修改或删除
					}
				}
				else { // 交易状态为“失败”
					out.println("fail"); // 请不要修改或删除
				}
				// ——请根据您的业务逻辑来编写程序（以上代码仅作参考）——

				// ////////////////////////////////////////////////////////////////////////////////////////
			}
			else {// 验证失败
				out.println("fail");
			}
		}
		catch (Exception e) {
			logger.error("为会员充值创建订单报错", e);
		}

		ActionContext.getContext().getActionInvocation().getProxy()
				.setExecuteResult(false);
		return NONE;
	}

	/**
	 * 添加充值记录
	 * 支付宝方式充值
	 */
	public void addBalance(BalanceOrderInfo balanceOrderInfo) {
		Account account = new Account();
		account.setId(balanceOrderInfo.getEaId());
		account = accountService.findAccountById(account);
		Member member = new Member();
		member.setId(balanceOrderInfo.getMemberId());
		member = memberService.getMemberById(member);
		Shop shop = new Shop();
		shop.setId(balanceOrderInfo.getShopId());
		shop = shopService.getShopById(shop);
		User user = new User();
		user.setId(balanceOrderInfo.getUserId());
		user = userService.getOneUser(user);
		
		Balance balance = new Balance();
		balance.setCreateTime(getCreateTime());
		balance.setEaId(balanceOrderInfo.getEaId());
		balance.setMemberId(balanceOrderInfo.getMemberId());
		balance.setShopId(balanceOrderInfo.getShopId());
		balance.setUserId(balanceOrderInfo.getUserId());
		balance.setMoney(balanceOrderInfo.getMoney());
		balance.setEaName(account != null ? account.getName() : "");
		balance.setShopName(shop != null ? shop.getName() : "");
		balance.setUserName(user != null ? user.getLoginName() : "");
		balance.setMemberName(member != null ? member.getName() : "");
		balance.setMemberMobile(member != null ? member.getMobile() : "");
		balance.setType(2); // 充值方式:支付宝充值
		balance.setDirectPayMoney(balanceOrderInfo.getDirectPayMoney());
		balanceService.addBalance(balance);
	}

	/**
	 * float精度处理
	 */
	private String floatToScale(float value) {
		BigDecimal decimal = new BigDecimal(value);
		return ""
				+ decimal.setScale(2, BigDecimal.ROUND_HALF_EVEN).floatValue();
	}

	/**
	 * 截取2个字符串中间的字符串
	 */
	private String subStringFrom(String str, String begin, String end) {
		int beginIndex = str.indexOf(begin);
		beginIndex += begin.length();
		int endIndex = str.indexOf(end);

		return str.substring(beginIndex, endIndex);
	}

	public BalanceOrderInfoService getBalanceOrderInfoService() {
		return balanceOrderInfoService;
	}

	public void setBalanceOrderInfoService(
			BalanceOrderInfoService balanceOrderInfoService) {
		this.balanceOrderInfoService = balanceOrderInfoService;
	}

	public TariffService getTariffService() {
		return tariffService;
	}

	public void setTariffService(TariffService tariffService) {
		this.tariffService = tariffService;
	}

	public ShopService getShopService() {
		return shopService;
	}

	public void setShopService(ShopService shopService) {
		this.shopService = shopService;
	}

	public BaseMemberService getBaseMemberService() {
		return baseMemberService;
	}

	public void setBaseMemberService(BaseMemberService baseMemberService) {
		this.baseMemberService = baseMemberService;
	}

	public BgiveRuleService getbGiveRuleService() {
		return bGiveRuleService;
	}

	public void setbGiveRuleService(BgiveRuleService bGiveRuleService) {
		this.bGiveRuleService = bGiveRuleService;
	}

	public EnterpriseIntegralRuleService getEnterpriseIntegralRuleService() {
		return enterpriseIntegralRuleService;
	}

	public void setEnterpriseIntegralRuleService(
			EnterpriseIntegralRuleService enterpriseIntegralRuleService) {
		this.enterpriseIntegralRuleService = enterpriseIntegralRuleService;
	}

	public MemberService getMemberService() {
		return memberService;
	}

	public void setMemberService(MemberService memberService) {
		this.memberService = memberService;
	}

	public BalanceService getBalanceService() {
		return balanceService;
	}

	public void setBalanceService(BalanceService balanceService) {
		this.balanceService = balanceService;
	}

	public AccountService getAccountService() {
		return accountService;
	}

	public void setAccountService(AccountService accountService) {
		this.accountService = accountService;
	}

	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	@Override
	public void setServletResponse(HttpServletResponse response) {
		this.response = response;
	}

	@Override
	public void setServletRequest(HttpServletRequest request) {
		this.request = request;
	}

}
